﻿using AbpApplication.Dto;
using AbpApplication.InPut;
using AbpEntityFrameworkcore.DbContext;
using AbpToDomain.View;
using AbpWebapi;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using NLog;
using NStandard;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using static AbpEntityFrameworkcore.DbContext.MyUserDbContext;

namespace AbpApplication.AppServices
{
    public class UserService : ApplicationService, MyUserService
    {
        private readonly UserManager<MyUser> userManager;
        private readonly RoleManager<MyRole> roleManager;

        private readonly IOptionsSnapshot<JWTSettings> jwtSettingsOpt;


        public UserService(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager, IOptionsSnapshot<JWTSettings> jwtSettingsOpt)
        {
            this.userManager = userManager;
            this.roleManager = roleManager;
            this.jwtSettingsOpt = jwtSettingsOpt;
        }
        public async Task<ApiResponse> RegisterUser(InPut_UserService inPut)//注册
        {
            try
            {
                if (await roleManager.RoleExistsAsync(inPut.Role) == false)
                {
                    MyRole role = new MyRole { Name = inPut.Role };
                    var result = await roleManager.CreateAsync(role);
                    if (!result.Succeeded) return new ApiResponse("roleManager.CreateAsync failed", false, null);
                }//添加角色
                MyUser user = await userManager.FindByNameAsync(inPut.Name);
                if (user != null)
                {
                    return new ApiResponse("用户已存在", false, null);
                }
                if (user == null)
                {
                    user = new MyUser { UserName = inPut.Name, PhoneNumber = inPut.Phone, Email = inPut.Email, Moniker = inPut.Moniker };
                    IdentityResult result = await userManager.CreateAsync(user, inPut.PassWord);
                    if (!result.Succeeded) return new ApiResponse(result.Errors.FirstOrDefault().Code, false, null);
                }//添加用户
                if (!await userManager.IsInRoleAsync(user, inPut.Role))
                {
                    var result = await userManager.AddToRoleAsync(user, inPut.Role);

                    await userManager.GenerateChangePhoneNumberTokenAsync(user, inPut.Phone);
                    if (!result.Succeeded) return new ApiResponse("roleManager.AddToRoleAsync failed", false, null);
                }//用户加入角色
                return new ApiResponse("注册成功", true, null);
            }

            catch (Exception ex)
            {
                Logger.LogWarning($"RegisterUser{inPut}" + ex.Message);
                return new ApiResponse("内部服务器错误", false, null);
            }
        }
        public async Task<ApiResponse> LoginUser(InPut_UserService2 inPut)//登录
        {
            try
            {
                MyUser user = await userManager.FindByNameAsync(inPut.username);
                if (user == null)
                {
                    return new ApiResponse("登录失败,请检查登录信息", false, null);
                }
                List<string> role = (List<string>)await userManager.GetRolesAsync(user);
                if (await userManager.CheckPasswordAsync(user, inPut.password))
                {
                    List<Claim> claims = new List<Claim>();
                    claims.Add(new Claim(ClaimTypes.Name, inPut.username));
                    claims.Add(new Claim(ClaimTypes.Role, role[0]));
                    string key = jwtSettingsOpt.Value.SecKey;//读取seckey的值
                    DateTime expire = DateTime.Now.AddSeconds(jwtSettingsOpt.Value.ExpireSeconds);
                    byte[] secBytes = Encoding.UTF8.GetBytes(key);
                    var secKey = new SymmetricSecurityKey(secBytes);
                    var credentilas = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);
                    var tokenDescriptor = new JwtSecurityToken(claims: claims, expires: expire, signingCredentials: credentilas);
                    string jwt = new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
                    //生成jwt
                    return new ApiResponse(user.Moniker, true, jwt);
                }
                return new ApiResponse("登录失败", false, null);
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"LoginUser{inPut}" + ex.Message);
                return new ApiResponse("内部服务器错误", false, null);
            }

        }
        public async Task<ApiResponse> UpdatePassWord(InPut_UserService3 inPut)//改密码
        {
            try
            {
                var user = await userManager.FindByNameAsync(inPut.UserName);
                if (user != null)
                {
                    IdentityResult result = await userManager.ChangePasswordAsync(user, inPut.PassWord, inPut.NewPassWord);
                    if (!result.Succeeded) return new ApiResponse(result.Errors.FirstOrDefault().Code, false, null);
                    else return new ApiResponse("修改成功", true, null);
                }
                return new ApiResponse("未查询到改用户", false, null);
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"UpdatePassWord{inPut}" + ex.Message);
                return new ApiResponse("内部服务器错误", false, null);
            }

        }
        public async Task<ApiResponse> UpdateUserInfo(InPut_UserService4 inPut)
        {
            try
            {
                var user = await userManager.FindByNameAsync(inPut.UserName);
                if (user != null)
                {
                    user.UserName = inPut.NewUserName;
                    user.PhoneNumber = inPut.PhoneNumber;
                    user.Email = inPut.Email;
                    user.Moniker = inPut.Moniker;
                    IdentityResult result = await userManager.UpdateAsync(user);
                    if (!result.Succeeded) return new ApiResponse(result.Errors.FirstOrDefault().Code, false, null);
                    else return new ApiResponse("修改成功", true, null);
                }
                return new ApiResponse("未查询到该用户", false, null);
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"UpdateUserInfo{inPut}" + ex.Message);
                return new ApiResponse("内部服务器错误", false, null);
            }

        }//更新用户信息
        public async Task<ApiResponse> FindOneUserInfo(string UserName)
        {
            try
            {
                var user = await userManager.FindByNameAsync(UserName);
                if (user != null) return new ApiResponse("获取成功", true, ObjectMapper.Map<MyUser, UserDto>(user));

                else return new ApiResponse("未查询到该用户", false, null);
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"FindOneUserInfo{UserName}" + ex.Message);
                return new ApiResponse("内部服务器错误", false, null);
            }

        }//查询单一用户
        public async Task<ApiResponse> UpdateRole(InPut_UserService5 inPut)//更新角色
        {
            try
            {

                if (await roleManager.RoleExistsAsync(inPut.Name) == false)
                {
                    MyRole role = new MyRole { Name = inPut.Name };
                    var Roresult = await roleManager.CreateAsync(role);
                    if (!Roresult.Succeeded) return new ApiResponse("roleManager.CreateAsync failed", false, null);
                }//添加角色
                var user = await userManager.FindByNameAsync(inPut.UserName);
                if (user == null) return new ApiResponse("未查询到该用户", false, null);
                if (await userManager.IsInRoleAsync(user, "管理员")) return new ApiResponse("无法修改管理员权限", false, null);
                var roles = await userManager.GetRolesAsync(user);  // 获取用户的所有角色
                await userManager.RemoveFromRolesAsync(user, roles);//删除该用户所有角色
                IdentityResult result = await userManager.AddToRoleAsync(user, inPut.Name);
                if (result.Succeeded) return new ApiResponse("更新角色成功", true, null);
                else return new ApiResponse("更新角色失败", true, null);
            }
            catch (Exception ex)
            {
                Logger.LogWarning($"UpdateRole{inPut}" + ex.Message);
                return new ApiResponse("内部服务器错误", false, null);

            }


        }

    }
}
